package com.wtwd.campus.receiver;

import com.alibaba.fastjson.JSONObject;
import com.wtwd.campus.annotation.MsgType;
import com.wtwd.campus.common.Constants;
import com.wtwd.campus.constant.SignConstant;
import com.wtwd.campus.dao.CommandRecordMapper;
import com.wtwd.campus.entity.*;
import com.wtwd.campus.h5_manager.entity.DeviceLog;
import com.wtwd.campus.h5_manager.service.DeviceLogService;
import com.wtwd.campus.service.*;
import com.wtwd.campus.utils.*;
import com.wtwd.campus.vcom.common.Constant;
import com.wtwd.campus.vcom.entity.VcomWarningRecord;
import com.wtwd.campus.vcom.service.VcomH5Service;
import com.wtwd.campus.wx.service.WxUtilsService;
import com.wtwd.campus.wx.utils.PushModel;
import com.wtwd.campus.wx.utils.WxUtils;
import org.apache.commons.lang.StringUtils;
import org.jeewx.api.core.req.model.message.TemplateMessageSendResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@MsgType(value = Constants.DEVICE_POWER_ON)
public class PowerOnDataReceiverHandler implements IReceiverHandler {

    @Value("${web.customerCode.xb}")
    private String xbCustomerCode;

    @Value("${web.customerCode.cw}")
    private String cwCustomerCode;

    @Value("${h5.customerId.hbDxRyh5}")
    private Integer hbDxRyh5CustomerId;

    @Value("${wx.general.push.customerCode}")
    private String wxPushCustomerCode;

    @Autowired
    private WxUtilsService wxUtilsService;


    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private IRMFeignClientService irmFeignClientService;
    @Autowired
    private CommandSendUtils commandSendUtils;
    @Resource
    private CommandRecordMapper commandRecordMapper;
    @Autowired
    private WarningRecordService warningRecordService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private PushUtils pushUtils;
    @Autowired
    private IRMFeignClientNettyService irmFeignClientNettyService;
    @Autowired
    private ReceiverUtils receiverUtils;
    @Autowired
    private WxService wxService;
    @Autowired
    private VcomH5Service vcomH5Service;
    @Autowired
    private DeviceLogService deviceLogService;

    @Override
    public void handlerMessage(MqMessage mqMessage) {
        MqPowerOnMessage mqPowerOnMessage = (MqPowerOnMessage) mqMessage.getObject();
        String imei = mqPowerOnMessage.getImei();
        String commandNumber = mqPowerOnMessage.getCommandNumber();
        String firmware = mqPowerOnMessage.getFirmware();
        Integer interval = mqPowerOnMessage.getInterval();
        String m1Card = mqPowerOnMessage.getM1Card();
        String uId = mqPowerOnMessage.getuId();
        String phone = mqPowerOnMessage.getPhone();
        if ("13912345678".equals(phone)) {
            phone = "";
        }
        Integer mode = mqPowerOnMessage.getMode();
        if (mode != 1) {
            //1实时定位模式，2省电模式
            mode = 2;
        }
        String answerVersion = mqPowerOnMessage.getAnswerVersion();
        String status = mqPowerOnMessage.getStatus();
        //处理指令上报的时间
        DeviceInfo deviceInfo = deviceInfoService.getDeviceByImei(imei);
        if (deviceInfo != null) {
            // 回复天气指令
            // *WT,866248050376688,WEATHER,122020,2,19,1,0#
            irmFeignClientService.replyWeather(imei, commandNumber);
            Long time = System.currentTimeMillis();
            if (deviceInfo.getDeviceType() == Constants.VCOM_DEVICE) {
                //存储威科姆开机提醒
                List<String> studentIds = vcomH5Service.getStudentIdByImei(imei);
                if (studentIds != null && studentIds.size() > 0) {
                    for (String studentId : studentIds) {
                        VcomWarningRecord record = new VcomWarningRecord();
                        record.setType(Constant.WARNING_POWER_ON);
                        record.setTime(time);
                        record.setImei(imei);
                        record.setStudentId("0");
                        if (!StringUtils.isBlank(studentId)) {
                            record.setStudentId(studentId);
                        }
                        vcomH5Service.addVcomWarningRecord(record);
                    }
                } else {
                    VcomWarningRecord record = new VcomWarningRecord();
                    record.setType(Constant.WARNING_POWER_ON);
                    record.setTime(time);
                    record.setImei(imei);
                    record.setStudentId("0");
                    vcomH5Service.addVcomWarningRecord(record);
                }
            } else {
                //存储一条开机提醒
                WarningRecord warningRecord = new WarningRecord();
                warningRecord.setWarning_time(time);
                warningRecord.setDevice_id(deviceInfo.getDeviceId());
                warningRecord.setAddress("");
                warningRecord.setWarning_type(Constants.POWER_ON_WARNING_TYPE);
                warningRecordService.addWarningRecord(warningRecord);
            }
            //如果是喜马拉雅的设备则进行绑定关系的指令下发
            if (!StringUtils.isBlank(deviceInfo.getOrgCode())) {
                String orgCode = deviceInfo.getOrgCode();
                if (orgCode.contains("A01A03A05") || orgCode.contains("A01A42")) {
                    Integer stuId = deviceInfo.getStudentId();
                    String studentName = "";
                    String className = "";
                    String schoolName = "";
                    Integer status2 = Constants.DEVICE_UNBINDING;
                    if (stuId != null) {
                        Map<String, Object> stuMap = studentService.getStuBindingMessByStuId(stuId);
                        studentName = (String) stuMap.get("studentName");
                        className = ((String) stuMap.get("gradeName")).concat((String) stuMap.get("classesName"));
                        schoolName = (String) stuMap.get("schoolName");
                        status2 = Constants.DEVICE_BINDING;
                    }
                    DeviceBindingStatus binding = new DeviceBindingStatus();
                    binding.setImei(imei);
                    binding.setCommandNumber(getCurTime());
                    binding.setStatus(status2);
                    binding.setStudentName(studentName);
                    binding.setSchoolName(schoolName);
                    binding.setClassesName(className);
                    // 进行绑定关系推送
                    logger.info("/收到开机指令，进行绑定关系下发： imei={},data={}", imei, binding.toString());
                    irmFeignClientService.setBindingStatus(binding);
                }
            }
            //修改设备信息
            deviceInfo.setLastUpTime(System.currentTimeMillis());
            deviceInfo.setFirmware(firmware);
            deviceInfo.setUpInterval(interval);
            deviceInfo.setM1Card(m1Card);
            deviceInfo.setSimCard(phone);
            deviceInfo.setWorkingPattern(mode);
            deviceInfoService.modifyDeviceInfo(deviceInfo);
            if (deviceInfo.getDeviceType() == Constants.HXY_DEVICE) {
                // 开机推送
                pushUtils.pushHxyPowerOn(imei, DateUtils.format(new Date(), DateUtils.dateFormat4));
            }
            // 针对离线缓存的指令，进行构建和发送
            // 1.查询该设备所有的离线存储指令
            List<Map<String, Object>> offLineRecord = deviceInfoService.getOffLineBufferCmd(imei);
            // 2.根据对应的类型构建成对应的对象，并且发送（可以调用CommandSendUtils,因为已经在线了，是否在线字段传true）
            for (Map<String, Object> record : offLineRecord) {
                String type = (String) record.get("cmd");
                String param = (String) record.get("param");
                Integer userId = (Integer) record.get("user_id");
                Integer offlineId = (Integer) record.get("id");
                CommandRecord commandRecord = commandRecordMapper.getCommandRecordByOfflineId(offlineId);
                logger.info("设备重启，发送离线缓存指令：".concat(commandRecord.getCommandType().concat(",").concat(commandRecord.getCommandContent())));
                commandSendUtils.sendOffLineCommand(type, param, imei, userId, commandRecord.getCommandNumber());
            }
            // 3.清空离线缓存表的指令（或者说查询出来就删除）
            deviceInfoService.deleteOffLineBufferCmd(imei);
            if (deviceInfo.getDeviceType() == Constants.CUSTOMER_DEVICE) {
                //开机推送（主要是四川启迪）
                pushUtils.pushPowerOnWarn(deviceInfo);
            }
            if (deviceInfo.getDeviceType() == Constants.H5_DEVICE) {//H5设备推送开机
                if (deviceInfo.getCustomerId() == 5 || deviceInfo.getCustomerId() == 8) {
                    pushUtils.hnh5PushAlarmInfo(deviceInfo.getImei(), "开机上报", DateUtils.format(new Date(), DateUtils.dateFormat1), null, null, null);
                } else if (hbDxRyh5CustomerId.equals(deviceInfo.getCustomerId())) {
                    HbDxE15RyPushEntity hbDxE15RyPushEntity = new HbDxE15RyPushEntity();
                    hbDxE15RyPushEntity.setImei(deviceInfo.getImei());
                    hbDxE15RyPushEntity.setmType(HbDxE15RyPushEntity.PushTypeEnum.ALARM_TYPE.getType());
                    hbDxE15RyPushEntity.setmClass(HbDxE15RyPushEntity.MessageType.START_UP_MESSAGE.getType());
                    hbDxE15RyPushEntity.setmTime(DateUtils.format(new Date(time), DateUtils.dateFormat4));
                    hbDxE15RyPushEntity.setMemo(MessageFormat.format(HbDxE15RyPushEntity.MessageType.START_UP_MESSAGE.getTemplate(), deviceInfo.getImei()));
                    HbDxE15RyUtiils.hbDxE15RyPush(hbDxE15RyPushEntity);
                }
            }
            //如果是平台设备，推送到微信（不推瑞翼和喜马拉雅）
            if (!StringUtils.isBlank(deviceInfo.getOrgCode()) && !deviceInfo.getOrgCode().contains("A01A03A05") && !deviceInfo.getOrgCode().contains("A01A07") && !deviceInfo.getOrgCode().contains("A01A38")) {
                //根据学生id查询推送openID
                if (deviceInfo.getStudentId() != null) {
                    List<Map<String, Object>> openIdList = wxService.getOpenIdByStuId(deviceInfo.getStudentId());
                    openIdList.stream().forEach(e -> {
                        String stuName = (String) e.get("student_name");
                        String openId = (String) e.get("open_id");
                        if (!StringUtils.isBlank(openId)) {
                            String content = stuName.concat("的校园卡已开机");
                            String tip = stuName.concat("的校园卡有一条新的开机记录");
                            if (deviceInfo.getOrgCode().startsWith(cwCustomerCode)) {
                                TemplateMessageSendResult sosRecordTemplate = PushModel.createWarningTemplateCW(stuName, time, content, tip);
                                sosRecordTemplate.setUrl("");
                                if (!StringUtils.isBlank(openId)) {
                                    sosRecordTemplate.setTouser(openId);
                                    WxUtils.pushMsgCW(sosRecordTemplate);
                                }
                            } else if (deviceInfo.getOrgCode().startsWith(xbCustomerCode)) {
                                TemplateMessageSendResult sosRecordTemplate = PushModel.createWarningTemplateXB(stuName, time, content, tip);
                                sosRecordTemplate.setTouser(openId);
                                WxUtils.pushMsgXB(sosRecordTemplate);
                            } else {
                                String pushCode = "";
                                if (StringUtils.isNotBlank(wxPushCustomerCode) && StringUtils.isNotBlank(deviceInfo.getOrgCode())) {
                                    List<String> customerCodeString = Arrays.asList(wxPushCustomerCode.split(SignConstant.COMMA));
                                    pushCode = wxUtilsService.getWxCustomerCode(customerCodeString, deviceInfo.getOrgCode());
                                    if (StringUtils.isNotBlank(pushCode)) {
                                        TemplateMessageSendResult warningTemplate = wxUtilsService.createWarningTemplate(pushCode, imei, stuName, time, content, tip);
                                        warningTemplate.setTouser(openId);
                                        wxUtilsService.pushMsg(pushCode, warningTemplate);
                                    }
                                }
                                if (StringUtils.isBlank(pushCode)) {
                                    TemplateMessageSendResult sosRecordTemplate = PushModel.createWarningTemplate(stuName, time, content, tip);
                                    sosRecordTemplate.setUrl("");
                                    if (!StringUtils.isBlank(openId)) {
                                        sosRecordTemplate.setTouser(openId);
                                        WxUtils.pushMsg(sosRecordTemplate);
                                    }
                                }
                            }
                        }
                    });
                }
            }
            //存储设备接收日志
            DeviceLog deviceLog = new DeviceLog();
            deviceLog.setSendUser(Constants.DEVICE_USER);
            deviceLog.setImei(imei);
            deviceLog.setBigType(Constants.DEVICE_POWER_ON);
            JSONObject contant = new JSONObject();
            contant.put("设备号", imei);
            contant.put("当前工作模式", mode);
            contant.put("当前上报间隔", interval);
            contant.put("固件版本", firmware);
            contant.put("m1Card", m1Card);
            contant.put("uId", uId);
            contant.put("号码", phone);
            deviceLog.setCmd(contant.toJSONString());
            deviceLog.setSendTime(System.currentTimeMillis());
            deviceLog.setCommandNumber(commandNumber);
            deviceLog.setState(1);
            deviceLogService.addDeviceLog(deviceLog);
        } else {
            saveUnInStorage(imei);
            receiverUtils.cloaseChannel(imei);
        }
    }

    /**
     * 获取当前时间的时分秒（HHmmss）
     *
     * @return
     */
    public String getCurTime() {
        Date d = new Date();
        SimpleDateFormat sbf = new SimpleDateFormat("HH:mm:ss");
        String format = sbf.format(d);
        String[] split = format.split(":");
        String time = split[0].concat(split[1]).concat(split[2]);
        return time;
    }
}
